package com.kexilo.messaging.processor;

import com.kexilo.messaging.domain.Message;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 消息处理器接口
 * 定义了消息处理的抽象接口，不依赖任何具体实现
 * 
 * @author Kexilo
 */
public interface MessageProcessor {
    
    /**
     * 处理消息
     * 
     * @param message 消息对象
     * @return 处理结果
     */
    ProcessResult process(Message message);
    
    /**
     * 异步处理消息
     * 
     * @param message 消息对象
     * @return 异步处理结果
     */
    CompletableFuture<ProcessResult> processAsync(Message message);
    
    /**
     * 批量处理消息
     * 
     * @param messages 消息列表
     * @return 批量处理结果
     */
    BatchProcessResult batchProcess(List<Message> messages);
    
    /**
     * 预处理消息（在实际处理前的准备工作）
     * 
     * @param message 消息对象
     * @return 预处理结果
     */
    default ProcessResult preProcess(Message message) {
        return ProcessResult.success("预处理完成");
    }
    
    /**
     * 后处理消息（在实际处理后的清理工作）
     * 
     * @param message 消息对象
     * @param processResult 处理结果
     * @return 后处理结果
     */
    default ProcessResult postProcess(Message message, ProcessResult processResult) {
        return ProcessResult.success("后处理完成");
    }
    
    /**
     * 处理失败时的处理逻辑
     * 
     * @param message 消息对象
     * @param exception 异常信息
     * @return 失败处理结果
     */
    default ProcessResult onProcessFailure(Message message, Exception exception) {
        return ProcessResult.failure("处理失败: " + exception.getMessage(), exception);
    }
    
    /**
     * 获取处理器名称
     * 
     * @return 处理器名称
     */
    String getProcessorName();
    
    /**
     * 获取支持的消息类型
     * 
     * @return 消息类型列表
     */
    List<String> getSupportedMessageTypes();
    
    /**
     * 是否支持该消息类型
     * 
     * @param messageType 消息类型
     * @return 是否支持
     */
    default boolean supports(String messageType) {
        return getSupportedMessageTypes().contains(messageType);
    }
    
    /**
     * 是否支持该消息
     * 
     * @param message 消息对象
     * @return 是否支持
     */
    default boolean supports(Message message) {
        return message != null && supports(message.getMessageType());
    }
    
    /**
     * 获取处理器优先级（数字越小优先级越高）
     * 
     * @return 优先级
     */
    default int getPriority() {
        return 100;
    }
    
    /**
     * 是否启用该处理器
     * 
     * @return 是否启用
     */
    default boolean isEnabled() {
        return true;
    }
    
    /**
     * 获取处理器描述
     * 
     * @return 描述信息
     */
    default String getDescription() {
        return getProcessorName() + " message processor";
    }
    
    /**
     * 获取处理统计信息
     * 
     * @return 统计信息
     */
    default Map<String, Object> getProcessStatistics() {
        return Map.of(
            "processorName", getProcessorName(),
            "enabled", isEnabled(),
            "supportedTypes", getSupportedMessageTypes()
        );
    }
    
    /**
     * 重置处理统计信息
     */
    default void resetStatistics() {
        // 默认空实现
    }
    
    /**
     * 处理结果
     */
    class ProcessResult {
        private final boolean success;
        private final String message;
        private final Throwable exception;
        private final Map<String, Object> context;
        private final long processingTime;
        private final String processorName;
        
        public ProcessResult(boolean success, String message, Throwable exception, 
                           Map<String, Object> context, long processingTime, String processorName) {
            this.success = success;
            this.message = message;
            this.exception = exception;
            this.context = context;
            this.processingTime = processingTime;
            this.processorName = processorName;
        }
        
        public ProcessResult(boolean success, String message) {
            this(success, message, null, Map.of(), 0L, null);
        }
        
        public ProcessResult(boolean success, String message, Throwable exception) {
            this(success, message, exception, Map.of(), 0L, null);
        }
        
        public static ProcessResult success() {
            return new ProcessResult(true, "处理成功");
        }
        
        public static ProcessResult success(String message) {
            return new ProcessResult(true, message);
        }
        
        public static ProcessResult success(String message, Map<String, Object> context) {
            return new ProcessResult(true, message, null, context, 0L, null);
        }
        
        public static ProcessResult failure(String message) {
            return new ProcessResult(false, message);
        }
        
        public static ProcessResult failure(String message, Throwable exception) {
            return new ProcessResult(false, message, exception);
        }
        
        public static ProcessResult retry(String message) {
            return new ProcessResult(false, message + " (需要重试)", null, 
                                   Map.of("needRetry", true), 0L, null);
        }
        
        public static ProcessResult ignore(String message) {
            return new ProcessResult(true, message + " (已忽略)", null, 
                                   Map.of("ignored", true), 0L, null);
        }
        
        // Getters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public Throwable getException() { return exception; }
        public Map<String, Object> getContext() { return context; }
        public long getProcessingTime() { return processingTime; }
        public String getProcessorName() { return processorName; }
        
        public boolean needRetry() {
            return context.containsKey("needRetry") && (Boolean) context.get("needRetry");
        }
        
        public boolean isIgnored() {
            return context.containsKey("ignored") && (Boolean) context.get("ignored");
        }
        
        @Override
        public String toString() {
            return String.format("ProcessResult{success=%s, message='%s', processingTime=%dms, processor='%s'}", 
                               success, message, processingTime, processorName);
        }
    }
    
    /**
     * 批量处理结果
     */
    class BatchProcessResult {
        private final int totalCount;
        private final int successCount;
        private final int failureCount;
        private final int ignoredCount;
        private final List<ProcessResult> results;
        private final long totalProcessingTime;
        private final String processorName;
        
        public BatchProcessResult(int totalCount, int successCount, int failureCount, int ignoredCount,
                                List<ProcessResult> results, long totalProcessingTime, String processorName) {
            this.totalCount = totalCount;
            this.successCount = successCount;
            this.failureCount = failureCount;
            this.ignoredCount = ignoredCount;
            this.results = results;
            this.totalProcessingTime = totalProcessingTime;
            this.processorName = processorName;
        }
        
        // Getters
        public int getTotalCount() { return totalCount; }
        public int getSuccessCount() { return successCount; }
        public int getFailureCount() { return failureCount; }
        public int getIgnoredCount() { return ignoredCount; }
        public List<ProcessResult> getResults() { return results; }
        public long getTotalProcessingTime() { return totalProcessingTime; }
        public String getProcessorName() { return processorName; }
        
        public boolean isFullSuccess() { return failureCount == 0; }
        public boolean isPartialSuccess() { return successCount > 0 && failureCount > 0; }
        public boolean isFullFailure() { return successCount == 0 && ignoredCount != totalCount; }
        public double getSuccessRate() { return totalCount == 0 ? 0.0 : (double) successCount / totalCount; }
        public double getAverageProcessingTime() { return totalCount == 0 ? 0.0 : (double) totalProcessingTime / totalCount; }
        
        @Override
        public String toString() {
            return String.format("BatchProcessResult{total=%d, success=%d, failure=%d, ignored=%d, " +
                               "successRate=%.2f%%, avgTime=%.2fms, processor='%s'}", 
                               totalCount, successCount, failureCount, ignoredCount,
                               getSuccessRate() * 100, getAverageProcessingTime(), processorName);
        }
    }
    
    /**
     * 抽象消息处理器
     * 提供通用的处理逻辑和统计功能
     */
    abstract class AbstractMessageProcessor implements MessageProcessor {
        protected long processedCount = 0;
        protected long successCount = 0;
        protected long failureCount = 0;
        protected long totalProcessingTime = 0;
        
        @Override
        public final ProcessResult process(Message message) {
            long startTime = System.currentTimeMillis();
            processedCount++;
            
            try {
                // 预处理
                ProcessResult preResult = preProcess(message);
                if (!preResult.isSuccess()) {
                    failureCount++;
                    return preResult;
                }
                
                // 实际处理
                ProcessResult result = doProcess(message);
                
                // 后处理
                ProcessResult postResult = postProcess(message, result);
                if (!postResult.isSuccess()) {
                    failureCount++;
                    return postResult;
                }
                
                if (result.isSuccess()) {
                    successCount++;
                } else {
                    failureCount++;
                }
                
                return result;
                
            } catch (Exception e) {
                failureCount++;
                return onProcessFailure(message, e);
            } finally {
                long processingTime = System.currentTimeMillis() - startTime;
                totalProcessingTime += processingTime;
            }
        }
        
        /**
         * 具体的处理逻辑（由子类实现）
         * 
         * @param message 消息对象
         * @return 处理结果
         */
        protected abstract ProcessResult doProcess(Message message);
        
        @Override
        public Map<String, Object> getProcessStatistics() {
            Map<String, Object> stats = MessageProcessor.super.getProcessStatistics();
            stats.put("processedCount", processedCount);
            stats.put("successCount", successCount);
            stats.put("failureCount", failureCount);
            stats.put("totalProcessingTime", totalProcessingTime);
            stats.put("successRate", processedCount == 0 ? 0.0 : (double) successCount / processedCount);
            stats.put("averageProcessingTime", processedCount == 0 ? 0.0 : (double) totalProcessingTime / processedCount);
            return stats;
        }
        
        @Override
        public void resetStatistics() {
            processedCount = 0;
            successCount = 0;
            failureCount = 0;
            totalProcessingTime = 0;
        }
    }
    
    /**
     * 消息处理监听器
     */
    interface ProcessListener {
        /**
         * 处理前事件
         * 
         * @param processor 处理器
         * @param message 消息对象
         */
        default void beforeProcess(MessageProcessor processor, Message message) {}
        
        /**
         * 处理成功事件
         * 
         * @param processor 处理器
         * @param message 消息对象
         * @param result 处理结果
         */
        default void onProcessSuccess(MessageProcessor processor, Message message, ProcessResult result) {}
        
        /**
         * 处理失败事件
         * 
         * @param processor 处理器
         * @param message 消息对象
         * @param result 处理结果
         */
        default void onProcessFailure(MessageProcessor processor, Message message, ProcessResult result) {}
        
        /**
         * 处理完成事件
         * 
         * @param processor 处理器
         * @param message 消息对象
         * @param result 处理结果
         */
        default void afterProcess(MessageProcessor processor, Message message, ProcessResult result) {}
    }
    
    /**
     * 注册处理监听器
     * 
     * @param listener 监听器
     */
    default void registerProcessListener(ProcessListener listener) {
        // 默认空实现
    }
    
    /**
     * 移除处理监听器
     * 
     * @param listener 监听器
     */
    default void removeProcessListener(ProcessListener listener) {
        // 默认空实现
    }
}
